package top.aicey.ai.sparring.controller;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import top.aicey.ai.sparring.common.constants.ErrorConstants;
import top.aicey.ai.sparring.common.holder.CurrentUser;
import top.aicey.ai.sparring.common.holder.UserHolder;
import top.aicey.ai.sparring.common.utils.BaseResponseUtil;
import top.aicey.ai.sparring.dto.enums.EvaluationStatusEnum;
import top.aicey.ai.sparring.dto.enums.RoleEnum;
import top.aicey.ai.sparring.dto.llm.EvaluateScoreInfo;
import top.aicey.ai.sparring.dto.model.BaseResponse;
import top.aicey.ai.sparring.dto.res.EvaluationReportResponse;
import top.aicey.ai.sparring.dto.res.EvaluationUserSceneHistoryResponse;
import top.aicey.ai.sparring.dto.res.UserCallLogResponse;
import top.aicey.ai.sparring.entity.SceneInstanceEvaluation;
import top.aicey.ai.sparring.entity.SceneInstanceLog;
import top.aicey.ai.sparring.entity.SceneQaPairs;
import top.aicey.ai.sparring.service.ISceneInstanceEvaluationService;
import top.aicey.ai.sparring.service.ISceneInstanceLogService;
import top.aicey.ai.sparring.service.ISceneQaPairsService;

/**
 * <p>
 * 用户评价内容 前端控制器
 * </p>
 *
 * @author 白杨
 * @since 2024-12-19
 */
@Api(tags = "AI陪练报告读取")
@RestController
@RequestMapping("/v3/sparing/evaluation")
public class TrainingSceneUserEvaluationController {

    @Autowired
    private ISceneInstanceEvaluationService sceneInstanceEvaluationService;

    @Autowired
    private ISceneInstanceLogService sceneInstanceLogService;

    @Autowired
    private ISceneQaPairsService sceneQaPairsService;

    @ApiOperation(value = "读取当前用户场景练习历史记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "scene_id",value = "场景id",required = true),
            @ApiImplicitParam(name = "limit",value = "限制条数",defaultValue = "20",required = false),
            @ApiImplicitParam(name = "x-access-token",value = "token",required = true,paramType = "header")
    })
    @GetMapping(value = "/scene/history")
    public BaseResponse<List<EvaluationUserSceneHistoryResponse>> sceneHistory(@RequestParam("scene_id") Long sceneId,@RequestParam(value = "limit",defaultValue = "20")Integer limit){
        if (Objects.isNull(sceneId) || sceneId < 0){
            return BaseResponseUtil.buildSuccessResponse(ErrorConstants.INVALID_PARAMS);
        }
        CurrentUser user = UserHolder.getUser();
        String userId = user.getUserId();

        List<EvaluationUserSceneHistoryResponse> list = sceneInstanceEvaluationService.sceneHistory(sceneId,userId,limit);

        return BaseResponseUtil.buildSuccessResponse(list);
    }


    @ApiOperation(value = "读取报告")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "record_id",value = "会话实例id",required = true),
            @ApiImplicitParam(name = "x-access-token",value = "token",required = true,paramType = "header")
    })
    @GetMapping(value = "/report")
    public BaseResponse<EvaluationReportResponse> report(@RequestParam("record_id") String recordId){
        if (Objects.isNull(recordId)){
            return BaseResponseUtil.buildSuccessResponse(ErrorConstants.INVALID_PARAMS);
        }
        SceneInstanceEvaluation sceneInstanceEvaluation = sceneInstanceEvaluationService.getByInstanceId(recordId);

        if (Objects.isNull(sceneInstanceEvaluation)){
            return BaseResponseUtil.buildSuccessResponse(ErrorConstants.INVALID_PARAMS);
        }

        EvaluationReportResponse response = new EvaluationReportResponse();


        response.setScore(sceneInstanceEvaluation.getScore());
        EvaluationStatusEnum statusEnum = EvaluationStatusEnum.getEnumByValue(sceneInstanceEvaluation.getStatus());
        response.setStatus(statusEnum);

        if (EvaluationStatusEnum.PROGRESS.equals(statusEnum)){
            // 无需继续往下查询了
            return BaseResponseUtil.buildSuccessResponse(response);
        }

        EvaluateScoreInfo evaluateScoreInfo = JSON.parseObject(sceneInstanceEvaluation.getContent(),EvaluateScoreInfo.class);

        response.setComment(evaluateScoreInfo.getComment());

        if (!MapUtils.isEmpty(evaluateScoreInfo.getDimensionScore())){
            Set<Map.Entry<String, Integer>> entries = evaluateScoreInfo.getDimensionScore().entrySet();

            List<EvaluationReportResponse.DimensionNode> dimensionNodes = Lists.newArrayList();
            for (Map.Entry<String, Integer> entry : entries) {
                dimensionNodes.add(new EvaluationReportResponse.DimensionNode(entry.getKey(),entry.getValue()));
            }

            response.setDimensionScore(dimensionNodes);
        }

        String moduleId = UserHolder.getUser().getModuleId();

        List<SceneQaPairs> qaPairs = sceneQaPairsService.listBySceneId(moduleId,sceneInstanceEvaluation.getSceneId());

        List<SceneInstanceLog> sceneInstanceLogs = sceneInstanceLogService.listByInstanceId(moduleId,recordId);


        List<UserCallLogResponse> responses = convertUserCallLogResponse(moduleId,sceneInstanceEvaluation.getCreatedBy(),sceneInstanceLogs,qaPairs);

        response.setUserCallLogResponses(responses);

        return BaseResponseUtil.buildSuccessResponse(response);
    }

    private List<UserCallLogResponse> convertUserCallLogResponse(String moduleId, String createUser, List<SceneInstanceLog> trainingSceneUserCallLogs, List<SceneQaPairs> qaPairs) {

        Map<Long, SceneQaPairs> qaPairsMap = qaPairs.stream().collect(Collectors.toMap(SceneQaPairs::getId, Function.identity()));

        List<UserCallLogResponse> responses = Lists.newArrayList();
        for (SceneInstanceLog trainingSceneUserCallLog : trainingSceneUserCallLogs) {
            UserCallLogResponse response = new UserCallLogResponse();
            response.setRole(trainingSceneUserCallLog.getRole());
            response.setTime(trainingSceneUserCallLog.getCreatedAt());
            response.setMessage(trainingSceneUserCallLog.getContent());
            if (RoleEnum.USER.equals(trainingSceneUserCallLog.getRole()) && Objects.nonNull(trainingSceneUserCallLog.getQaPairId())){
                Long qaPairId = trainingSceneUserCallLog.getQaPairId();
                if (qaPairsMap.containsKey(qaPairId)){
                    response.setStandardMessage(qaPairsMap.get(qaPairId).getAnswer());
                }
            }
            responses.add(response);
        }

        return responses;
    }

}
